initial commit of a weibo user agent

Albert Sun 11 jaren geleden
bovenliggende
commit
e494721db7
3 gewijzigde bestanden met toevoegingen van 198 en 0 verwijderingen
  1. 119 0
      app/models/agents/weibo_user_agent.rb
  2. 52 0
      spec/data_fixtures/one_weibo.json
  3. 27 0
      spec/models/agents/weibo_user_agent_spec.rb

+ 119 - 0
app/models/agents/weibo_user_agent.rb

@@ -0,0 +1,119 @@
1
+require "weibo_2"
2
+
3
+module Agents
4
+  class WeiboUserAgent < Agent
5
+    cannot_receive_events!
6
+
7
+    description <<-MD
8
+      The WeiboUserAgent follows the timeline of a specified Weibo user. It uses this endpoint: http://open.weibo.com/wiki/2/statuses/user_timeline/en
9
+
10
+      You must first set up a Weibo app and generate an `acess_token` to authenticate with. Provide that, along with the `app_key` and `app_secret` for your Weibo app in the options.
11
+
12
+      Specify the `uid` of the Weibo user whose timeline you want to watch.
13
+
14
+      Set `expected_update_period_in_days` to the maximum amount of time that you'd expect to pass between Events being created by this Agent.
15
+    MD
16
+
17
+    event_description <<-MD
18
+      Events are the raw JSON provided by the Twitter API. Should look something like:
19
+
20
+        {
21
+          "created_at": "Tue May 31 17:46:55 +0800 2011",
22
+          "id": 11488058246,
23
+          "text": "求关注。",
24
+          "source": "<a href=\"http://weibo.com\" rel=\"nofollow\">新浪微博</a>",
25
+          "favorited": false,
26
+          "truncated": false,
27
+          "in_reply_to_status_id": "",
28
+          "in_reply_to_user_id": "",
29
+          "in_reply_to_screen_name": "",
30
+          "geo": null,
31
+          "mid": "5612814510546515491",
32
+          "reposts_count": 8,
33
+          "comments_count": 9,
34
+          "annotations": [],
35
+          "user": {
36
+              "id": 1404376560,
37
+              "screen_name": "zaku",
38
+              "name": "zaku",
39
+              "province": "11",
40
+              "city": "5",
41
+              "location": "北京 朝阳区",
42
+              "description": "人生五十年,乃如梦如幻;有生斯有死,壮士复何憾。",
43
+              "url": "http://blog.sina.com.cn/zaku",
44
+              "profile_image_url": "http://tp1.sinaimg.cn/1404376560/50/0/1",
45
+              "domain": "zaku",
46
+              "gender": "m",
47
+              "followers_count": 1204,
48
+              "friends_count": 447,
49
+              "statuses_count": 2908,
50
+              "favourites_count": 0,
51
+              "created_at": "Fri Aug 28 00:00:00 +0800 2009",
52
+              "following": false,
53
+              "allow_all_act_msg": false,
54
+              "remark": "",
55
+              "geo_enabled": true,
56
+              "verified": false,
57
+              "allow_all_comment": true,
58
+              "avatar_large": "http://tp1.sinaimg.cn/1404376560/180/0/1",
59
+              "verified_reason": "",
60
+              "follow_me": false,
61
+              "online_status": 0,
62
+              "bi_followers_count": 215
63
+          }
64
+        }
65
+    MD
66
+
67
+    default_schedule "every_1h"
68
+
69
+    def validate_options
70
+      unless options[:uid].present? &&
71
+        options[:expected_update_period_in_days].present? &&
72
+        options[:app_key].present? &&
73
+        options[:app_secret].present? &&
74
+        options[:access_token].present?
75
+        errors.add(:base, "expected_update_period_in_days, uid, app_key, app_secret and access_token are required")
76
+      end
77
+    end
78
+
79
+    def working?
80
+      (event = event_created_within(options[:expected_update_period_in_days].to_i.days)) && event.payload.present?
81
+    end
82
+
83
+    def default_options
84
+      {
85
+          :uid => "",
86
+          :access_token => "---",
87
+          :app_key => "---",
88
+          :app_secret => "---",
89
+          :expected_update_period_in_days => "2"
90
+      }
91
+    end
92
+
93
+    def check
94
+      WeiboOAuth2::Config.api_key = options[:app_key] # WEIBO_APP_KEY
95
+      WeiboOAuth2::Config.api_secret = options[:app_secret] # WEIBO_APP_SECRET
96
+      client = WeiboOAuth2::Client.new
97
+      client.get_token_from_hash :access_token => options[:access_token]
98
+
99
+
100
+      since_id = memory[:since_id] || nil
101
+      opts = {:uid => options[:uid].to_i}
102
+      opts.merge! :since_id => since_id unless since_id.nil?
103
+
104
+      # http://open.weibo.com/wiki/2/statuses/user_timeline/en
105
+      resp = client.statuses.user_timeline opts
106
+      if resp[:statuses]
107
+
108
+
109
+        resp[:statuses].each do |status|
110
+          memory[:since_id] = status.id if !memory[:since_id] || (status.id > memory[:since_id])
111
+
112
+          create_event :payload => status.as_json
113
+        end
114
+      end
115
+
116
+      save!
117
+    end
118
+  end
119
+end

+ 52 - 0
spec/data_fixtures/one_weibo.json

@@ -0,0 +1,52 @@
1
+{
2
+    "statuses": [
3
+      {
4
+        "created_at": "Tue May 31 17:46:55 +0800 2011",
5
+        "id": 11488058246,
6
+        "text": "求关注。",
7
+        "source": "<a href=\"http://weibo.com\" rel=\"nofollow\">新浪微博</a>",
8
+        "favorited": false,
9
+        "truncated": false,
10
+        "in_reply_to_status_id": "",
11
+        "in_reply_to_user_id": "",
12
+        "in_reply_to_screen_name": "",
13
+        "geo": null,
14
+        "mid": "5612814510546515491",
15
+        "reposts_count": 8,
16
+        "comments_count": 9,
17
+        "annotations": [],
18
+        "user": {
19
+            "id": 1404376560,
20
+            "screen_name": "zaku",
21
+            "name": "zaku",
22
+            "province": "11",
23
+            "city": "5",
24
+            "location": "北京 朝阳区",
25
+            "description": "人生五十年,乃如梦如幻;有生斯有死,壮士复何憾。",
26
+            "url": "http://blog.sina.com.cn/zaku",
27
+            "profile_image_url": "http://tp1.sinaimg.cn/1404376560/50/0/1",
28
+            "domain": "zaku",
29
+            "gender": "m",
30
+            "followers_count": 1204,
31
+            "friends_count": 447,
32
+            "statuses_count": 2908,
33
+            "favourites_count": 0,
34
+            "created_at": "Fri Aug 28 00:00:00 +0800 2009",
35
+            "following": false,
36
+            "allow_all_act_msg": false,
37
+            "remark": "",
38
+            "geo_enabled": true,
39
+            "verified": false,
40
+            "allow_all_comment": true,
41
+            "avatar_large": "http://tp1.sinaimg.cn/1404376560/180/0/1",
42
+            "verified_reason": "",
43
+            "follow_me": false,
44
+            "online_status": 0,
45
+            "bi_followers_count": 215
46
+        }
47
+    }
48
+  ],
49
+   "previous_cursor": 0,
50
+    "next_cursor": 11488013766,
51
+    "total_number": 81655
52
+}

+ 27 - 0
spec/models/agents/weibo_user_agent_spec.rb

@@ -0,0 +1,27 @@
1
+require 'spec_helper'
2
+
3
+describe Agents::WeiboUserAgent do
4
+  before do
5
+    # intercept the twitter API request for @tectonic's user profile
6
+    stub_request(:any, /api.weibo.com/).to_return(:body => File.read(Rails.root.join("spec/data_fixtures/one_weibo.json")), :status => 200)
7
+  
8
+    @opts = {
9
+      :uid => "123456",
10
+      :expected_update_period_in_days => "2",
11
+      :app_key => "asdfe",
12
+      :app_secret => "asdfe",
13
+      :access_token => "asdfe"
14
+    }
15
+
16
+    @checker = Agents::WeiboUserAgent.new(:name => "123456 fetcher", :options => @opts)
17
+    @checker.user = users(:bob)
18
+    @checker.save!
19
+  end
20
+
21
+  describe "#check" do
22
+    it "should check for changes" do
23
+      lambda { @checker.check }.should change { Event.count }.by(1)
24
+    end
25
+  end
26
+
27
+end